<?php
/**
 * 处理人与人的关系，人与部门的关系等
 * @author ray andycao
 */
apf_require_class("Bll_BLL");
apf_require_class("Const_Work");
apf_require_class("Const_Util");
class Bll_Hr_UserRelation extends BLL
{
    /**
     * 根据职位获取uid
     *
     * @param int|array $jobids
     * @param int $is_parttime
     * @param int $is_deleted
     */
    public function get_job_user_list ($jobids, $is_parttime = 1, $is_deleted = 1)
    {
        $data = array();
        if (empty($jobids)) {
            return $data;
        }
        if (is_array($jobids)) {
            $_where = array(
                    "job_id IN (" . implode(',', $jobids) . ") AND 1=?" => 1
            );
        } else {
            $_where = array(
                    'job_id' => intval($jobids)
            );
        }
        $_where['is_parttime'] = $is_parttime;
        $_where['is_deleted'] = $is_deleted;

        $data = $this->get_work_dao()->find($_where, '', 0);
        return $data;
    }

    /**
     * 根据员工id得到职位信息
     *
     * @param int|array $uids
     * @param int $is_parttime
     * @param int $is_deleted
     * @return multitype: unknown
     */
    public function get_job_by_uids ($uids, $is_parttime = 1, $is_deleted = 1)
    {
        $data = array();
        if (empty($uids)) {
            return $data;
        }
        if (is_array($uids)) {
            $_where = array(
                    "user_id IN (" . implode(',', $uids) . ") AND 1=?" => 1
            );
        } else {
            $_where = array(
                    'user_id' => intval($uids)
            );
        }
        if ($is_parttime == 1 || $is_parttime == 2) {
            $_where['is_parttime'] = $is_parttime;
        }
        if ($is_deleted == 1 || $is_deleted == 2) {
            $_where['is_deleted'] = $is_deleted;
        }

        $data = $this->get_work_dao()->find($_where, '', 0);
        return $data;
    }
    /**
     * 更新员工职位和部门的在职人数
     *
     * @param int $uid
     * @param int $add  0是岗位和部门人数减1 1是加
     */
    public function update_dep_position ($uid, $add = 0)
    {
        // 获取人员职位信息,去掉人员职位关系
        // 人员职位信息 更新岗位人数,更新部门人数
        $status = true;
        $user_job = $this->get_work_dao()->find(array('user_id' => $uid), '', 0);
        if (empty($user_job)) {
            return $status;
        }
        $job_ids = array();
        $dep_job_up = array(
                'fact_num' => 'fact_num-1'
        );
        if ($add) {
            $dep_job_up = array(
                    'fact_num' => 'fact_num+1'
            );
        }
        foreach ($user_job as $val) {
            if ($val['is_deleted'] == 1 && $val['is_parttime'] == 1) { // 1未删除
                $job_ids[] = $val['job_id'];
                $this->get_job_bll()->update_job_by_id($val['job_id'],
                        $dep_job_up, true);
            }
        }
        $job_list = $this->get_job_bll()->find_by_job_ids($job_ids);
        $dep_ids = array();
        foreach ($job_list as $val) {
            $this->get_dep_bll()->update_department($val['department_id'],
                    $dep_job_up, true);
        }
        return $status;
    }

    /**
     * 建立员工关系
     *
     * @param int $user_id 用户ID
     * @param int $user_job 用户JOBID
     * @param int $parent_id 主管ID
     * @param int $parent_job 主管JOBID
     * @param int $is_direct 1：直接主管，2：虚线主管
     */
    public function add_user_report_relation ($user_id, $user_job, $parent_id, $parent_job, $is_direct = 1){
        if (empty($user_id) || empty($user_job) || empty($parent_id) ||empty($parent_job)) {
            return false;
        } elseif ($this->check_same_relation($user_id, $user_job, $parent_id,$parent_job)){         // 检测是否存在相同关系
            return false;
        } elseif ($this->_check_user_relation($user_id, $parent_id, $parent_job)) { // 检测user是否为parent的上级（防止死循环）
            return false;
        } elseif (! $this->_check_work($user_id, $user_job) || ! $this->_check_work($parent_id, $parent_job)) { // 检测两者WORK是否存在
            return false;
        } elseif ($is_direct == 1 && $this->_check_direct($user_id, 1)) { // 检测是否已经有直线主管
            return false;
        }
        $data = array(
                'user_id' => intval($user_id),
                'user_job_id' => intval($user_job),
                'parent_id' => intval($parent_id),
                'parent_job_id' => intval($parent_job),
                'is_direct' => intval($is_direct),
                'created' => time()
        );
        return $this->get_userrelation_dao()->insert($data);
    }

    /**
     * 添加用户任职信息
     * @param array $data
     * @return 0|insert_id
     */
    public function add_user_work($data, $user_id,$work_type){
        if(!$data['job_id'] || !$data['work_time']){
            return 0;
        }
        $data['is_deleted']   = Const_Util::IS_DELETE_NO;
        $data['created']     = intval(time());
        $data['last_update'] = date('Y-m-d H:i:s');
        $data['user_id']     = $user_id;
        $data['is_parttime'] = $work_type;
        if(isset($data['work_id'])){
            unset($data['work_id']);
        }
        return $this->get_work_dao()->insert($data);
    }
    /**
     * 更新用户任职信息
     * @param int $user_id
     * @param array $data
     */
    public function update_user_work($work_id, $data){

        $work_id = intval($work_id);
        if(!$work_id){
            return '';
        }
        $data['last_update'] = date('Y-m-d H:i:s');
        if(isset($data['work_id'])){
            unset($data['work_id']);
        }
        return $this->get_work_dao()->update_by_id($work_id,$data);
    }
    /**
     * 检查是否存在直线（虚线）主管
     *
     * @param unknown_type $user_id
     * @param unknown_type $is_direct
     */
    private function _check_direct ($user_id, $is_direct = 1)
    {
        $data = array(
                'user_id' => intval($user_id),
                'is_direct' => intval($is_direct),
                'is_deleted' => 1
        );
        return $this->get_userrelation_dao()->find($data);
    }

    /**
     * 检查是否存在该WORK
     *
     * @param unknown_type $user_id
     * @param unknown_type $user_job
     * @return multitype: unknown
     */

    private function _check_work($user_id, $user_job){
        if(empty($user_id) || empty($user_job)){
            return false;
        }
        $data = array(
                'user_id' => intval($user_id),
                'job_id' => intval($user_job),
                'is_deleted' => 1
        );

        return $this->get_work_dao()->find($data);
    }

    /**
     * 检测是否有相同的关系
     *
     * @param unknown_type $user_id
     * @param unknown_type $user_job
     * @param unknown_type $parent_id
     * @param unknown_type $parent_job
     * @return boolean
     */
    public function check_same_relation ($user_id, $user_job, $parent_id, $parent_job)
    {
        if (empty($user_id) || empty($user_job) || empty($parent_id) || empty($parent_job)) {
            return false;
        }
        $data = array(
                'user_id' => intval($user_id),
                'user_job_id' => intval($user_job),
                'parent_id' => intval($parent_id),
                'parent_job_id' => intval($parent_job),
                'is_deleted' => 1
        );
        return $this->get_userrelation_dao()->find($data);
    }

    /**
     * 检查是否存在parent_id的上级是user_id
     *
     * @param int $user_id
     * @param int $parent_id
     * @return array:
     */
   private function _check_user_relation ($user_id, $parent_id, $parent_job)
    {
        $parent_ids = $this->_get_all_parent($parent_id, $parent_job);
        if($parent_ids !== false){
            return in_array($user_id, $parent_ids);
        }else{
            return true;
        }
    }

    /**
     * 查找所有父ID
     *
     * @param unknown_type $user_id
     * @return Ambigous <multitype:, multitype:unknown >
     */
    private function _get_all_parent ($user_id, $user_job ,$is_direct = 3)
    {
        $return = array();
        $temp = array();
        $re = $this->get_user_parent($user_id, $user_job, $is_direct);
        if ($re) {
            foreach ($re as $val) {
                if(!in_array($val['parent_id'], $return)){
                    $return[] = $val['parent_id'];
                    if(!in_array($user_id, $return)){//检查自己是自己上级的情况
                        $temp = $this->_get_all_parent($val['parent_id'],$val['parent_job_id']);
                    }else{
                        $return = false;
                        break;
                    }
                    $return = array_merge($return, $temp);
                }
            }
        }

        return $return;
    }

    /**
     * 删除员工关系
     *
     * @param int $relation_id
     *            该条关系的ID
     */
    public function delete_user_report_relation ($relation_id)
    {
        if (empty($relation_id)) {
            return false;
        }
        // 该关系是否存在
        $data = array(
                'is_deleted' => 2
        );
        return $this->get_userrelation_dao()->update_by_id(intval($relation_id),
                $data);
    }
    /**
     * portal 中同步的work
     */
    public function add_relation_from_portal($data){
        $this->get_userrelation_dao()->insert($data);
    }
    /**
     * portal 中同步的work
     */
    public function delete_relation_from_portal($data,$where){
        $this->get_userrelation_dao()->update($data,$where);
    }
    /**
     * 根据老job和user_id 更新成新JOB
     * @param unknown_type $user_id
     * @param unknown_type $old_job
     * @param unknown_type $new_job
     * @return boolean
     */
    public function update_work_from_portal($user_id,$old_job,$new_job){
        $reutrn = false;
        if(empty($user_id) || empty($old_job) || empty($new_job)){
            return $reutrn;
        }
        $data  = array('job_id'=>$new_job);
        $where = array('user_id'=>$user_id,'job_id'=>$old_job);
        return $this->get_work_dao()->update($data,$where);
    }
    /**
     * 员工离职,解除所有作为下级的关系
     *
     * @param int $user_id
     */
    public function delete_user_report_by_uid ($user_id)
    {
        if (empty($user_id)) {
            return false;
        }
        $data = array(
                'is_deleted' => 2
        );
        return $this->get_userrelation_dao()->update($data,
                array(
                        'user_id' => $user_id
                ));
    }

    /**
     * 获得员工上级（一级）
     *
     * @param int $user_id 员工ID
     * @param int $user_job 员工职位
     * @param int $is_direct 1：直接主管，2：虚线主管, 3:全部
     */
    public function get_user_parent ($user_id, $user_job=0, $is_direct = 1)
    {
        if (empty($user_id)) {
            return false;
        }
        $where = array(
                'is_deleted' => 1,
                'user_id' => intval($user_id),
        );
        if($user_job){
            $wherep['user_job_id'] = intval($user_job);
        }
        if (3 != $is_direct) {
            $where['is_direct'] = intval($is_direct);
        }
        return $this->get_userrelation_dao()->find($where);
    }

    /**
     * 获得员工下级（一级）
     *
     * @param int $user_id 员工ID
     * @param int $is_direct 1：直接主管，2：虚线主管, 3:全部
     */
    public function get_user_sub ($user_id, $parent_job, $is_direct = 1)
    {
        if (empty($user_id)) {
            return false;
        }
        $where = array(
                'is_deleted' => 1,
                'parent_id' => intval($user_id),
                'parent_job_id' => intval($parent_job)
        );
        if (3 != $is_direct) {
            $where['is_direct'] = intval($is_direct);
        }
        return $this->get_userrelation_dao()->find($where);
    }

    /**
     * 获得员工下级（一级）总数
     *
     * @param int $user_id 员工ID
     * @param int $is_direct 1：直接主管，2：虚线主管, 3:全部
     */
    public function get_user_sub_count ($user_id, $parent_job, $is_direct = 1)
    {
        if (empty($user_id)) {
            return false;
        }
        $where = array(
                'is_deleted' => 1,
                'parent_id' => intval($user_id),
                'parent_job_id' => intval($parent_job)
        );
        if (3 != $is_direct) {
            $where['is_direct'] = intval($is_direct);
        }
        return $this->get_userrelation_dao()->find_count($where);
    }

    /**
     * 主管转岗，更新主管跟手下的关系
     *
     * @param unknown_type $parent_id
     * @param unknown_type $old_job_id
     * @param unknown_type $job_id
     */
    public function update_sub_relation ($parent_id, $old_job_id, $job_id)
    {
        if (empty($parent_id) || empty($old_job_id) || empty($job_id)) {
            return false;
        }
        $data = array(
                'parent_job_id' => $job_id
        );
        $where = array(
                'parent_id' => $parent_id,
                'parent_job_id' => $old_job_id,
                'is_deleted' => 1
        );

        return $this->get_userrelation_dao()->update($data, $where);
    }

    /**
     * 删除满足条件的主管
     *
     * @param unknown_type $user_id
     * @param unknown_type $old_job_id
     */
    public function delete_parent_relation ($user_id, $old_job_id)
    {
        if (empty($user_id) || empty($old_job_id)) {
            return false;
        }
        $data = array( 'is_deleted' => 2);
        $where = array('user_id' => $user_id, 'user_job_id' => $old_job_id, 'is_deleted' => 1);
        return $this->get_userrelation_dao()->update($data, $where);
    }

    /**
     * 批量修改用户职位
     *
     * @param array $uids
     * @param int $job_id
     * @return boolean
     */
    public function update_multi_user_work ($uids, $job_id)
    {
        $status = false;
        if (empty($uids)) {
            return $status;
        }
        $where = array(
                "user_id IN(" . implode(',', $uids) . ") AND 1=?" => 1,
                'is_parttime' => 1,
                'is_deleted' => 1
        );
        $data = $this->get_work_dao()->find($where, '', 0);
        if (empty($data)) {
            return $status;
        }
        $work_time = date('Ymd');
        foreach ($data as $val) {
            // 先解除关系
            $this->get_user_bll()->delete_user_work($val['user_id'],$val['work_id']);
            $this->get_user_bll()->add_user_work($val['user_id'], $job_id,$work_time);
            //更新连带下级关系中的职位
            $this->update_sub_relation($val['user_id'],$val['job_id'],$job_id);

            $this->update_user_relation_jobid($val['user_id'], $val['job_id'],$job_id);
        }
        //取职位信息,更改work_city_id
        $job_data = $this->get_job_bll()->get_job_dep_info($job_id);
        $this->get_user_bll()->update_work_city_id($uids,$job_data['city_id']);
        return true;
    }
    /**
     * 更新员工的职位id
     * @param int $user_id
     * @param int $job_id
     */
    public function update_user_relation_jobid($user_id, $old_job_id, $new_job_id,$new_parent_id=0){
        $data = array(
            'user_job_id'=>$new_job_id
                );
        //如果设置了上级，一起更新上级信息
        if($new_parent_id){
            $re = $this->get_user_bll()->get_user_work($new_parent_id);
            if(!$re){
                return false;
            }
            $data['parent_id'] = $new_parent_id;
            $data['parent_job_id'] = $re['job_id'];
        }
        $where = array(
                'user_id'=>$user_id,
                'user_job_id'=>$old_job_id,
                'is_deleted'=>1
                );
        return $this->get_userrelation_dao()->update($data,$where);
    }
    /**
     * 直属上级关系
     * @param int $user_id
     * @param int $job_id
     * @return array(relation_rows,parent_name,parent_job_name):
     */
    public function get_director_direct_yes($user_id,$job_id,$need_name = true){
        $work_derector_direct_yes = array();
        $user_id = intval($user_id);
        $job_id  = intval($job_id);
        if(!$user_id || !$user_id){
            return $work_derector_direct_yes;
        }
        $work_derector_direct_yes = $this->get_user_parent($user_id,$job_id,Const_Work::DIRECTOR_IS_DIRECT_YES);
        if(!$need_name){
            return $work_derector_direct_yes[0];
        }
        if(!empty($work_derector_direct_yes)){
            $work_derector_direct_yes = $work_derector_direct_yes[0];

            $temp_derector = $this->get_user_bll()->get_user_by_id($work_derector_direct_yes['parent_id']);
            $work_derector_direct_yes['parent_name'] = $temp_derector['real_name'];//主管名

            $temp_derector_work = $this->get_job_bll()->find_by_job_id($work_derector_direct_yes['parent_job_id']);
            $work_derector_direct_yes['parent_job_name'] = $temp_derector_work['position_name'];//主管职务名称
        }
        return $work_derector_direct_yes;
    }
     /**
     * 直属上级关系
     * @param int $user_id
     * @param int $job_id
     * @return array(relation_rows,parent_name,parent_job_name):
     */
    public function get_director_direct_yes_new($user_id,$job_id,$parent_name = true,$parent_job_name = false){
        $work_derector_direct_yes = array();
        $user_id = intval($user_id);
        $job_id  = intval($job_id);
        if(!$user_id || !$user_id){
            return $work_derector_direct_yes;
        }
        $work_derector_direct_yes = $this->get_user_parent($user_id,$job_id,Const_Work::DIRECTOR_IS_DIRECT_YES);
        if(!empty($work_derector_direct_yes)){

            $work_derector_direct_yes = $work_derector_direct_yes[0];
            if($parent_name){
                $temp_derector = $this->get_user_bll()->get_user_by_id($work_derector_direct_yes['parent_id']);
                $work_derector_direct_yes['parent_name'] = $temp_derector['real_name'];//主管名
            }
            if($parent_job_name){
                $temp_derector_work = $this->get_job_bll()->find_by_job_id($work_derector_direct_yes['parent_job_id']);
                $work_derector_direct_yes['parent_job_name'] = $temp_derector_work['position_name'];//主管职务名称
            }
        }
        return $work_derector_direct_yes;
    }
    /**
     * 虚线上级关系
     * @param int $user_id
     * @param int $job_id
     * @return array(array(relation_rows,parent_name,parent_job_name)...)
     */
    public function get_director_direct_no($user_id,$job_id, $need_name = true){
        $work_derector_direct_no = array();
        $user_id = intval($user_id);
        $job_id  = intval($job_id);
        if(!$user_id || !$user_id){
            return $work_derector_direct_no;
        }
        $work_derector_direct_no = $this->get_user_parent($user_id,$job_id,Const_Work::DIRECTOR_IS_DIRECT_NO);
        if(!$need_name){
            return $work_derector_direct_no;
        }
        if(!empty($work_derector_direct_no)){
            $temp_parent_ids = array();//主管ids
            $temp_parent_job_ids = array();//主管职务
            foreach($work_derector_direct_no as $temp){
                $temp_parent_ids[] = $temp['parent_id'];
                $temp_parent_job_ids[] = $temp['parent_job_id'];
            }

            //主管名
            $temp_derectors = $this->get_user_bll()->get_user_by_ids($temp_parent_ids);//print_r($temp_derectors);exit;
            $temp_key_id_derectors = array();
            foreach($temp_derectors as $temp){
                $temp_key_id_derectors[$temp['user_id']] = $temp['real_name'];
            }
            //职位名
            $temp_derectors_job = $this->get_job_bll()->find_by_job_ids($temp_parent_job_ids,Const_Util::IS_DELETE_NO);
            $temp_key_id_derectors_job = array();
            foreach($temp_derectors_job as $temp){
                $temp_key_id_derectors_job[$temp['job_id']] = $temp['position_name'];
            }
            foreach($work_derector_direct_no as $key=>$temp){
                $work_derector_direct_no[$key]['parent_name'] = $temp_key_id_derectors[$temp['parent_id']];
                $work_derector_direct_no[$key]['parent_job_name'] = $temp_key_id_derectors_job[$temp['parent_job_id']];
            }
        }
        return $work_derector_direct_no;
    }
    /**
     * 批量修改用户的直属领导
     *
     * @param array $uids
     * @param int $parent_uid
     * @param int $parent_job_id
     */
    public function update_multi_user_parent ($uids, $parent_uid, $parent_job_id){
        $status = false;
        if (empty($uids)) {
            return $status;
        }
        $where = array(
                "user_id IN(" . implode(',', $uids) . ") AND 1=?" => 1,
                'is_parttime' => 1,
                'is_deleted' => 1
        );
        $data = $this->get_work_dao()->find($where, '', 0);
        if (empty($data)) {
            return $status;
        }
        foreach ($data as $val) {// 先解除关系
            $this->delete_parent_relation($val['user_id'], $val['job_id']);
            $this->add_user_report_relation($val['user_id'], $val['job_id'],$parent_uid, $parent_job_id);
        }
        return true;
    }

    /**
     * 根据用户id得到用户的职位和岗位信息
     * @param int $uid
     */
    public function get_user_job_info($uids){
        $data = array();
        if(empty($uids)){
            return $data;
        }
        $work_data = $this->get_job_by_uids($uids);
        if(empty($work_data)){
            return $data;
        }
        $tmp_dep_ids = array();
        $tmp_job_ids = array();
        foreach($work_data as $val){
            $tmp_job_ids[$val['user_id']] = $val['job_id'];
        }
        $jobids = array_unique(array_values($tmp_job_ids));
        $job_data = $this->get_job_bll()->find_by_job_ids($jobids);

        foreach($job_data as $val){
            $tmp_dep_ids[$val['job_id']] = $val['department_id'];
        }

        $depids = array_unique(array_values($tmp_dep_ids));
        $dep_data = $this->get_dep_bll()->get_department_by_ids($depids);

        foreach($tmp_job_ids as $uid=>$val){
            $depid = $tmp_dep_ids[$val];
            $data[$uid]['job_info'] = $job_data[$val];
            $data[$uid]['dep_info'] = $dep_data[$depid];
        }
        return $data;
    }
    /**
     * 遍历等级关系,直属主管 outterface
     * @param array $uids
     */
    public function get_user_relation($uids){
        $data = array();
        if(empty($uids)){
            return $data;
        }
        $uids = array_unique($uids);
        foreach($uids as $val){
            $data[$val] = $this->_get_all_parent($val,0,1);
        }
        return $data;
    }
    /**
     * 查找部门管理人
     * @param unknown_type $depid
     */
    public function get_department_manager($depid){
        $manager = 0;
        //先查找一个job
        $job_data = $this->get_job_bll()->get_job_by_dep($depid,1);
        if(empty($job_data)){
            return $manager;
        }
        $jobid = array_keys($job_data);
        $jobid = $jobid[0];
        //查找这个job下的一个人
        $work_data = $this->get_work_dao()->find_row(array('job_id'=>$jobid));
        if(empty($work_data)){
            return $manager;
        }
        //得到这个人的所有领导
        $parent_list = $this->_get_all_parent($work_data['user_id'],0,1);
        if(empty($parent_list)){
            return $manager;
        }
        //查找领导的所在的职位是否在同一个部门，不在的则为部门领导
        $work_info = $this->get_user_job_info($parent_list);
        foreach($parent_list as $val){
            $p_depid = $work_info[$val]['dep_info']['department_id'];
            if($p_depid != $depid){
                $manager = $val;
                break;
            }
        }
        return $manager;

    }
    /**
     *查询这些员工的直属领导
     * @param array $uids
     * @return multitype:|multitype:unknown
     */
    public function get_user_last_parent($uids){
        $data = array();
        if(empty($uids)){
            return $data;
        }
        $_where=array(
                "user_id IN(".implode(',',$uids).") AND 1=?"=>1,
        );
        //肯定是最后一个领导
        $list = $this->get_userrelation_dao()->find($_where,'relation_id desc ',0);
        if(!empty($list)){
            foreach($list as $val){
                if(empty($data[$val['user_id']])){//因为有多条所以只处理第一条的记录
                    $data[$val['user_id']] = $val['parent_id'];
                }
            }
        }
        return $data;
    }
    /**
     * 获取所有上下级关系
     * @param unknown_type $is_direct
     */
    public function get_all_relation($is_direct=1){
        $_where['is_deleted']= 1;
        if($is_direct !=-1){
            $_where['is_direct']= $is_direct;
        }
        return $this->get_userrelation_dao()->find($_where,'',0);
    }
    //department
    private $dep_bll = null;
    //job
    private $job_bll = null;
    //user
    private $user_bll = null;

    private function get_dep_bll ()
    {
        if (! isset($this->dep_bll)) {
            apf_require_class('Bll_Hr_Department');
            $this->dep_bll = new Bll_Hr_Department();
        }
        return $this->dep_bll;
    }

    private function get_job_bll ()
    {
        if (! isset($this->job_bll)) {
            apf_require_class('Bll_Hr_Job');
            $this->job_bll = new Bll_Hr_Job();
        }
        return $this->job_bll;
    }

    private function get_user_bll ()
    {
        if (! isset($this->user_bll)) {
            apf_require_class('Bll_Hr_User');
            $this->user_bll = new Bll_Hr_User();
        }
        return $this->user_bll;
    }
    // hroa.work
    private function get_work_dao ()
    {
        $dao = $this->get_dao('Dao_Hr_Work');
        return $dao;
    }

    private function get_userrelation_dao ()
    {
        $dao = $this->get_dao('Dao_Hr_Relation');
        return $dao;
    }
}